package org.osgroup.project;

import org.osgroup.visitor.BaseVisitor;

import java.util.concurrent.atomic.AtomicLong;

/**
 * 项目基类
 * 
 * <p>所有游乐园项目的基类，包括游乐设施和美食街</p>
 * <p>提供心跳监控机制，用于监控项目运行状态</p>
 * 
 * @author OS Group
 * @version 1.0
 */
public class BaseProject {
    public String getProjectName() {
        return projectName;
    }

    public void setProjectName(String projectName) {
        this.projectName = projectName;
    }

    public double getProjectX() {
        return projectX;
    }

    public void setProjectX(double projectX) {
        this.projectX = projectX;
    }

    public double getProjectY() {
        return projectY;
    }

    public void setProjectY(double projectY) {
        this.projectY = projectY;
    }

    public BaseVisitor[] getBaseVisitor() {
        return baseVisitor;
    }

    public void setBaseVisitor(BaseVisitor[] baseVisitor) {
        this.baseVisitor = baseVisitor;
    }

    public boolean isOk() {
        return isOk;
    }

    public void setOk(boolean ok) {
        isOk = ok;
    }

    public int getPeopleNum() {
        return peopleNum;
    }

    public void setPeopleNum(int peopleNum) {
        this.peopleNum = peopleNum;
    }

    private String projectName;//项目名
    private double projectX;//项目X坐标
    private double projectY;//项目Y坐标
    private int peopleNum;//当前游玩本项目的人数
    private BaseVisitor[] baseVisitor;//目前游玩该项目的游客列表
    private boolean isOk;//该游乐项目是否正常
    
    // ==================== 心跳监控相关字段 ====================
    
    /** 最后一次心跳时间戳 */
    private AtomicLong lastHeartbeatTime;
    
    /** 心跳间隔时间(毫秒) - 默认5秒 */
    private long heartbeatInterval = 1000;
    
    /** 心跳超时时间(毫秒) - 默认15秒 */
    private long heartbeatTimeout = 10000;
    
    /** 心跳计数器 */
    private AtomicLong heartbeatCount;
    
    /** 自动心跳线程 */
    private Thread autoHeartbeatThread;
    
    /** 是否启用自动心跳 */
    private volatile boolean autoHeartbeatEnabled = false;
    
    /**
     * 默认构造函数 - 初始化心跳监控
     */
    public BaseProject() {
        this.lastHeartbeatTime = new AtomicLong(System.currentTimeMillis());
        this.heartbeatCount = new AtomicLong(0);
        this.sendHeartbeat();
    }
    
    // ==================== 心跳监控方法 ====================
    
    /**
     * 发送心跳信号
     * 更新最后心跳时间，表明项目正常运行
     */
    public void sendHeartbeat() {
        long currentTime = System.currentTimeMillis();
        lastHeartbeatTime.set(currentTime);
        long count = heartbeatCount.incrementAndGet();
        
        // 可以记录日志或通知监控系统
        if (count % 10 == 0) { // 每10次心跳输出一次
            System.out.println("💓 [心跳] " + projectName + " - 第 " + count + " 次心跳 | " + 
                               "状态: " + (isOk ? "正常" : "异常"));
        }
    }
    
    /**
     * 检查项目是否存活（通过心跳超时判断）
     * 
     * @return true表示项目存活，false表示心跳超时
     */
    public boolean isAlive() {
        long currentTime = System.currentTimeMillis();
        long lastHeartbeat = lastHeartbeatTime.get();
        long timeSinceLastHeartbeat = currentTime - lastHeartbeat;
        
        return timeSinceLastHeartbeat < heartbeatTimeout;
    }
    
    /**
     * 获取距离上次心跳的时间(毫秒)
     * 
     * @return 距离上次心跳的毫秒数
     */
    public long getTimeSinceLastHeartbeat() {
        long currentTime = System.currentTimeMillis();
        return currentTime - lastHeartbeatTime.get();
    }
    
    /**
     * 获取心跳统计信息
     * 
     * @return 心跳统计字符串
     */
    public String getHeartbeatStatus() {
        long timeSince = getTimeSinceLastHeartbeat();
        boolean alive = isAlive();
        
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("【%s 心跳状态】\n", projectName));
        sb.append(String.format("  存活状态: %s\n", alive ? "✅ 正常" : "❌ 超时"));
        sb.append(String.format("  心跳次数: %d\n", heartbeatCount.get()));
        sb.append(String.format("  距上次心跳: %.2f 秒\n", timeSince / 1000.0));
        sb.append(String.format("  心跳间隔: %.2f 秒\n", heartbeatInterval / 1000.0));
        sb.append(String.format("  超时阈值: %.2f 秒\n", heartbeatTimeout / 1000.0));
        
        return sb.toString();
    }
    
    /**
     * 重置心跳计数器
     */
    public void resetHeartbeat() {
        lastHeartbeatTime.set(System.currentTimeMillis());
        heartbeatCount.set(0);
        System.out.println("🔄 [心跳重置] " + projectName + " 心跳监控已重置");
    }
    
    /**
     * 启动自动心跳线程
     * 项目会在后台线程中自动发送心跳,不会阻塞主线程
     */
    public void startAutoHeartbeat() {
        if (autoHeartbeatEnabled) {
            System.out.println("⚠️  [自动心跳] " + projectName + " 已经启动自动心跳");
            return;
        }
        
        autoHeartbeatEnabled = true;
        autoHeartbeatThread = new Thread(() -> {
            System.out.println("💓 [自动心跳] " + projectName + " 启动自动心跳线程");
            
            while (autoHeartbeatEnabled && !Thread.interrupted()) {
                try {
                    sendHeartbeat();
                    Thread.sleep(heartbeatInterval);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
            
            System.out.println("💓 [自动心跳] " + projectName + " 停止自动心跳线程");
        });
        
        autoHeartbeatThread.setDaemon(true);
        autoHeartbeatThread.setName("AutoHeartbeat-" + projectName);
        autoHeartbeatThread.start();
    }
    
    /**
     * 停止自动心跳线程
     */
    public void stopAutoHeartbeat() {
        if (!autoHeartbeatEnabled) {
            return;
        }
        
        autoHeartbeatEnabled = false;
        
        if (autoHeartbeatThread != null) {
            autoHeartbeatThread.interrupt();
            try {
                autoHeartbeatThread.join(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        
        System.out.println("🛑 [自动心跳] " + projectName + " 已停止自动心跳");
    }
    
    /**
     * 检查自动心跳是否启用
     */
    public boolean isAutoHeartbeatEnabled() {
        return autoHeartbeatEnabled;
    }
    
    // ==================== Getter和Setter ====================
    
    public long getHeartbeatInterval() {
        return heartbeatInterval;
    }
    
    public void setHeartbeatInterval(long heartbeatInterval) {
        this.heartbeatInterval = heartbeatInterval;
    }
    
    public long getHeartbeatTimeout() {
        return heartbeatTimeout;
    }
    
    public void setHeartbeatTimeout(long heartbeatTimeout) {
        this.heartbeatTimeout = heartbeatTimeout;
    }
    
    public long getHeartbeatCount() {
        return heartbeatCount.get();
    }
    
    public long getLastHeartbeatTime() {
        return lastHeartbeatTime.get();
    }
    
    // ==================== 原有方法 ====================
    
    /**
     * 检票方法
     * 
     * @return true表示检票通过
     */
    public boolean check() {
        // 发送心跳信号
        sendHeartbeat();
        return isOk;
    }
}
